///////////////////////////
//http和Socket的封装
//////////////////////////
import { ImageAsset, SpriteFrame, assetManager } from 'cc';
import proto from '../ProtoBuf/proto.js';
import { Gamer, RoomInfo } from './StorageInfo';
import { Log } from './Util';
import { Wechat } from '../Market/Wechat';


export const env: "develop" | "test" | "release" = "develop";

/**微信支付环境 0正式 1测试 */
export const wechatEnv: 0 | 1 = 0
console.log('当前支付环境为', wechatEnv);
//在线图片资源
export const resource = {
  develop: "http://192.168.1.200:8080/resource",//本地服务器
  trial: "https://oss.ldlymj.com/ddz/resource",//体验测试服务器
  release: "https://oss.ldlymj.com/ddz/resource",//线上服务器
}
//网络请求以及套接字
export const URLS = {
  develop: {
    // http: "http://192.168.1.36:8080",//本地开发者服务器
    http: "http://192.168.1.200:8888",//本地服务器
    // socket: "ws://192.168.1.51:9200/ddz",//本地开发者服务器
    socket: "ws://192.168.1.200:9200/ddz"//本地服务器,
  },
  trial: {
    http: "https://test.ldlymj.com/ddzbg",
    socket: "wss://test.ldlymj.com/ddz"
  },
  release: {
    http: "https://ddz.ldlymj.com/ddzbg",
    socket: "wss://ddz.ldlymj.com/ddz"
  }
}
// console.log('当前服务器环境为', URLS[new Wechat().getEnv()]);
//用来加载图片资源
export class LoadUrlImg {
  private url: string;
  /**非必要不传默认有地址指向 */
  constructor(url: string = resource[new Wechat().getEnv()]) {
    this.url = url;
  }
  /**地址后面拼接的地址 */
  getFrame(dir: string): Promise<SpriteFrame> {
    // console.log("当前请求图片的地址", this.url);
    return new Promise((res, rej) => {
      if (dir.length < 4) dir = '/not.png';
      assetManager.loadRemote<ImageAsset>(this.url.concat(dir), { ext: '.png' }, (err, img_data) => {
        if (!err) res(SpriteFrame.createWithImage(img_data));
        else rej("没有找到对应的图片");
      });
    });
  }
}

/**封装request*/
export class Http<T> extends XMLHttpRequest {
  static URL: string = URLS[new Wechat().getEnv()].http;
  constructor(callfun: (data: T, url?: string) => void) {
    super();
    // this.withCredentials = true;
    this.onerror = () => Log.error("请求错误");
    this.onload = (suc) => { //监听请求完成数据
      // Log.success("请求完成：", suc);
      if (this.status === 200 && this.readyState === 4) {
        // this.responseText        
        callfun(JSON.parse(this.responseText), Http.URL);
        // console.log("http请求数据", JSON.parse(this.responseText));
      } else {
        callfun(undefined);
        Log.error("请求失败：", this);
      }
    }
  }
  setUrl(url: string) {
    Http.URL = url;
    return this;
  }
  /**微信分享成功查询接口 */
  share(uid: number) {
    this.open("GET", Http.URL.concat("/gapi/share/", uid.toString()));
    this.setRequestHeader("x-token", new Gamer().token);
    this.send();
  }
  /**获取接口地址数据 */
  loadURLS(env: 'develop' | 'trial' | 'release') {
    this.open("POST", "https://ddz.ldlymj.com/ddzbg/gapi/base/server/config");
    this.send(JSON.stringify({ env_vsersion: env }));
    return this;
  }
  /**web登录接口 */
  loginweb(body: LoginWeb) {
    let fromdata = new FormData();
    this.open("POST", Http.URL.concat("/gapi/base/login/web"));
    fromdata.append("accName", body.accName);
    this.send(fromdata);
  }
  /**微信登录接口 */
  loginwx(body: LodinWx) {
    this.open("POST", Http.URL.concat("/gapi/base/login/wx"));
    this.setRequestHeader("Content-type", "application/json");
    const obj = {
      rawData: body.rawData,
      signature: body.signature,
      code: body.code,
      iv: body.iv,
      encryptedData: body.encryptedData
    }
    this.send(JSON.stringify(obj));
  }
  /**获取玩家信息 */
  gamerinfo(infoConfig: GamerInfo) {
    this.open("GET", Http.URL.concat("/gapi/user/info"));
    this.setRequestHeader("x-token", new Gamer().token);
    this.send(JSON.stringify(infoConfig));
  }
  /**获取战绩列表 */
  recordlist() {
    this.open("GET", Http.URL.concat("/gapi/user/gaming_record"));
    this.setRequestHeader("x-token", new Gamer().token);
    this.send(JSON.stringify({
      "month": 0,
      "page": 1,
      "pageSize": 0,
      "select": 0
    }));
  }
  /**获取背包内容 */
  baglist() {
    this.open("GET", Http.URL.concat("/gapi/bag/list"));
    this.setRequestHeader("x-token", new Gamer().token);
    this.send();
  }
  /**获取房间配置roomlist */
  roolist() {
    this.open("GET", Http.URL.concat("/gapi/room/list"));
    this.setRequestHeader("x-token", new Gamer().token);
    this.send();
  }
  /**商品数据 */
  shoop() {
    this.open("GET", Http.URL.concat("/gapi/shop/list"));
    this.setRequestHeader("x-token", new Gamer().token);
    this.send();
  }
  /**微信支付成功后数据回传 */
  paysuc(data: { outTradeNo: string }) {
    this.open('POST', Http.URL.concat("/gapi/pay/notify/wx"));
    this.setRequestHeader("Content-type", "application/json");
    this.setRequestHeader("x-token", new Gamer().token);
    this.send(JSON.stringify(data));
  }
  /**微信支付预订单 拿到订单号 */
  prepay(data: prepayType) {
    this.open("POST", Http.URL.concat("/gapi/pay/prepay/wx"));
    this.setRequestHeader("Content-type", "application/json");
    this.setRequestHeader('x-token', new Gamer().token);
    this.send(JSON.stringify(data));
  }
  /**非人名币商品购买*/
  shopbuy(data: shopbuyType) {
    this.open("POST", Http.URL.concat("/gapi/shop/buy"));
    this.setRequestHeader('Content-type', 'application/json');
    this.setRequestHeader('x-token', new Gamer().token);
    this.send(JSON.stringify(data));
  }
  /**反馈消息列表 */
  submitList() {
    this.open("GET", Http.URL.concat('/gapi/feedback/list'));
    this.setRequestHeader('x-token', new Gamer().token);
    this.send();
  }
  /**提交反馈 */
  submit(data: SubmitType) {
    this.open("POST", Http.URL.concat('/gapi/feedback/submit'));
    this.setRequestHeader('x-token', new Gamer().token);
    this.send(JSON.stringify(data));
  }
  /**获取当前月签到数据 */
  signin() {
    this.open('GET', Http.URL.concat('/gapi/signin/list'))
    this.setRequestHeader('x-token', new Gamer().token);
    this.send()
  }
  /**发起签到 */
  sendSignin(body: sendSigninType) {
    this.open('POST', Http.URL.concat('/gapi/signin/sign'));
    this.setRequestHeader('x-token', new Gamer().token);
    this.send(JSON.stringify(body))
  }
  /**获取救济金详情 */
  AlmsDetail() {
    this.open('GET', Http.URL.concat('/gapi/benefit/detail'));
    this.setRequestHeader('x-token', new Gamer().token);
    this.send()
  }
  /**获取签到详情 */
  ReceiveAlms(type: number) {
    this.open('POST', Http.URL.concat('/gapi/benefit/receive'));
    this.setRequestHeader('x-token', new Gamer().token);
    this.send(JSON.stringify({ type }));
  }
  /**获取抽奖奖品列表 */
  reward_list() {
    this.open("GET", Http.URL.concat('/gapi/turntable/reward_list'))
    this.setRequestHeader('x-token', new Gamer().token)
    this.send()
  }
  /**开始抽奖 */
  turntableDraw(times: number) {
    this.open("GET", Http.URL.concat(`/gapi/turntable/draw?times=${times}`))
    this.setRequestHeader('x-token', new Gamer().token)
    this.send()
  }
  /**任务列表 */
  taskList() {
    this.open('GET', Http.URL.concat("/gapi/task/list"))
    this.setRequestHeader('x-token', new Gamer().token)
    this.send()
  }
  /**领取任务 */
  receiveTask(body: { id: number, item_id: number }) {
    this.open('POST', Http.URL.concat("/gapi/task/receive"))
    this.setRequestHeader('Content-type', 'application/json');
    this.setRequestHeader('x-token', new Gamer().token)
    this.send(JSON.stringify(body))
  }
}
//-------------以下为类型限制接口--------//
export interface SucType<T> {
  code: number
  data: T
  msg: string
}
/**任务列表 */
export interface TaskList {
  id: number;
  name: string;
  list: List[];
}
export interface List {
  id: number;
  item_id: number;
  title: string;
  amount: number;
  expectant: number;
  user_expectant: number;
  image: string;
  desc: string;
  status: number;
}
/**抽奖奖品列表&&开始抽奖 */
export interface Reward {
  id: number;
  name: string;
  group: number;
  percent: number;
  image: string;
}
/**救济金详情 */
export interface AlmsDetail {
  alltimes: number;
  residue_time: number;
  srate: number;
  status: number;
  times: number;
}
/**发起签到 */
export interface sendSigninType {
  day: number
}
/**返回当前月签到数据 */
export interface signinType {
  code: number;
  data: {
    continuous: number
    total: number
    list: sign[]
  };
  msg: string;
}

export interface sign {
  day: number;
  image: string;
  name: string;
  status: number;
}
//**客户反馈返回的消息 */
export interface SubmitListType {
  code: number;
  data: MsgItem[];
  msg: string;
}

export interface MsgItem {
  id: number;
  uid: number;
  content: string;
  isback: number;
  status: number;
  CreatedAt: string;
}
//**客户反馈提交 */
export interface SubmitType {
  Content: string
}
/**微信支付预订单 */
export interface prepayType {
  goods_id: number;
  sandbox: boolean;
}
/**预订单号接口类型 */
export interface perpayData {
  code: number
  data: {
    buyQuantity: number
    outTradeNo: string
  }
  msg: string
}
/**非人名币商品购买 */
export interface shopbuyType {
  goods_id: number
}

/**网页登陆接口类型限制*/
export interface LoginWeb {
  accName: string;
}
/**微信登录接口类型限制*/
export interface LodinWx {
  rawData: string;
  signature: string;
  code: string;
  encryptedData: string;
  iv: string;
}
/**房间配置*/
/**房间配置数据结构 */
export interface RoomConfig {
  code: number;
  data: Datum_[];
  msg: string;
}
export interface Datum_ {
  game_type: number;
  name: string;
  mode_group: number;
  type_list: Typelist[];
}

export interface Typelist {
  name: string;
  play_type: number;
  rooms: Room_[];
}

export interface Room_ {
  id: number;
  game_type: number;
  play_type: number;
  room_type: number;
  name: string;
  consume: number;
  difficulty: number;
  base_score: number;
  max_score: number;
  fee: number;
  entermin: number;
  entermax: number;
  online_min: number;
  online_max: number;
}
// export interface Datum {
//   game_type: number;
//   name: string;
//   mode_group: number;
//   rooms: Room_[];
// }
// export interface Room_ {
//   id: number;
//   game_type: number;
//   play_type: number;
//   room_type: number;
//   name: string;
//   consume: number;
//   difficulty: number;
//   base_score: number;
//   max_score: number;
//   fee: number;
//   entermin: number;
//   entermax: number;
//   online_min: number;
//   online_max: number;
// }
/**玩家信息*/
export interface GamerInfo {
  source: string;
  uid: string;
}

export interface GamerData {
  code: number;
  data: Data;
  msg: string;
}

interface Data {
  uid: number;
  CreatedAt: string;
  nickname: string;
  sex: number;
  avatarType: number;
  avatar: string;
  diamond: number;
  coin: number;
  ingot: number;
  point: number;
  vip: number;
  lastLoginTime: string;
  loginIp: string;
  matchNum: number;
  winCount: number;
  maxWinSreak: number;
  maxRecord: MaxRecord;
}

interface MaxRecord {
  spring: number;
  bomb: number;
  multiple: number;
  winCoin: number;
  title: number;
  duan: number;
}

interface MaxRecord {
  spring: number;
  bomb: number;
  multiple: number;
  winCoin: number;
  title: number;
  duan: number;
}

/**商城数据 */
export interface ShoopData {
  code: number;
  data: Datum[];
  msg: string;
}
export interface Datum {
  id: number;
  group: number;
  name: string;
  desc: string;
  consume: number;
  price: number;
  image: string;
  qq_goodid: string;
}

/**封装套接字Websocket */
export class Socket extends WebSocket {
  static URL = URLS[new Wechat().getEnv()].socket;
  heard_beat_: Function = null //心跳包
  constructor({
    open,
    message,
    close,
    error = (err) => {
      Log.error('连接错误!!!')
    },
  }: msgEnt) {
    super(Socket.URL)//线上服务器
    // this.binaryType = 'blob';
    this.onmessage = message
    this.onopen = open
    this.onclose = close
    this.onerror = error
    Log.info('发起ws连接')
  }
  /**发送指令*/
  private sendCmd(code: ServerEventCode, data: string = '', info: string = '') {
    // console.log('指令', code);
    const req =
      proto.com.handsome.landlords.entity.ClientTransferDataProtoc.create({
        code: String(code),
        data: data,
        info: info,
      }) //创建proto数据
    // console.log('加密前数据', req);
    const res =
      proto.com.handsome.landlords.entity.ClientTransferDataProtoc.encode(req) //加密
    this.send((res.finish() as Uint8Array).slice().buffer)
  }
  /**登录*/
  login(data: { id: string; version: string; mode?: '1' }) {
    this.sendCmd(ServerEventCode.CODE_CLIENT_LOGIN, JSON.stringify(data))
  }
  /**创建房间人机房*/
  createPVE_ROOM(roomId: number | string) {
    this.sendCmd(ServerEventCode.CODE_ROOM_CREATE_PVE, String(roomId))
  }
  /**开始游戏 */
  startGame() {
    this.sendCmd(ServerEventCode.CODE_GAME_STARTING)
  }
  /**退出房间 */
  exitRoom() {
    let roomid = new RoomInfo().id;
    console.log(roomid);
    if (roomid) {
      this.sendCmd(ServerEventCode.CODE_ROOM_LEAVE, String(roomid))
    } else {
      this.sendCmd(ServerEventCode.CODE_ROOM_LEAVE, String(0))
    }
  }
  /**创建房间好友房 */
  createCREATE_ROOM(roomId: number) {
    this.sendCmd(ServerEventCode.CODE_ROOM_CREATE, String(roomId))
  }
  /**加入房间 */
  JOIN_ROOM(roomId: string) {
    this.sendCmd(ServerEventCode.CODE_ROOM_JOIN, roomId)
  }
  /**抢地主*/
  landlord_elect(bol: boolean) {
    this.sendCmd(ServerEventCode.CODE_GAME_LANDLORD_ELECT, String(bol))
  }
  /**加倍 */
  choose_double(bol: number) {
    this.sendCmd(ServerEventCode.CODE_GAME_POKER_CHOOSE_DOUBLE, String(bol))
  }
  /**出牌指令*/
  poker_play(arr: string[]) {
    // console.log('出牌指令------>',JSON.stringify(arr));
    this.sendCmd(ServerEventCode.CODE_GAME_POKER_PLAY, JSON.stringify(arr))
  }
  /**不出/过*/
  poker_paly_pass() {
    this.sendCmd(ServerEventCode.CODE_GAME_POKER_PLAY_PASS)
  }
  /**托管*/
  change_trustee(bol: boolean = true) {
    this.sendCmd(ServerEventCode.CODE_GAME_CHANGE_TRUSTEE, JSON.stringify(bol))
  }
  /**心跳包*/
  heard_beat() {
    this.sendCmd(ServerEventCode.CODE_CLIENT_HEAD_BEAT)
  }
}

//-------------以下为类型限制接口--------//
interface msgEnt {
  open: (ev: Event) => void
  message: (ev: MessageEvent<any>) => void
  close: (this: WebSocket, ev: CloseEvent) => any
  error?: (ev: Event) => void
}

/**指令类型 */
export enum ServerEventCode {
  /**心跳包*/
  CODE_CLIENT_HEARD_BEAT,
  /**玩家退出3p */
  CODE_CLIENT_EXIT,
  /**玩家退出4p */
  CODE_4P_CLIENT_EXIT,
  /**玩家离线 */
  CODE_CLIENT_OFFLINE,
  /**设置客户端信息 */
  CODE_CLIENT_INFO_SET,
  /**登录 */
  CODE_CLIENT_LOGIN,
  /**不出 */
  CODE_CLIENT_HEAD_BEAT,
  /**创建pvp房间*/
  CODE_ROOM_CREATE,
  /**创建pvp4人房间*/
  CODE_4P_ROOM_CREATE,
  /**创建pve房间*/
  CODE_ROOM_CREATE_PVE,
  /**获取房间列表*/
  CODE_GET_ROOMS,
  /**加入房间*/
  CODE_ROOM_JOIN,
  /**加入房间4p*/
  CODE_4P_ROOM_JOIN,
  /**游戏开始*/
  CODE_GAME_STARTING,
  /**游戏开始4p*/
  CODE_4P_GAME_STARTING,
  /**玩家准备*/
  CODE_GAME_READY,
  /**抢地主*/
  CODE_GAME_LANDLORD_ELECT,
  /**抢地主4p*/
  CODE_4P_GAME_LANDLORD_ELECT,
  /**出牌环节*/
  CODE_GAME_POKER_PLAY,
  /**出牌环节4p*/
  CODE_4P_GAME_POKER_PLAY,
  /**出牌重定向*/
  CODE_GAME_POKER_PLAY_REDIRECT,
  /**出牌重定向4p*/
  CODE_4P_GAME_POKER_PLAY_REDIRECT,
  /**过*/
  CODE_GAME_POKER_ON_PASS,
  /**不出*/
  CODE_GAME_POKER_PLAY_PASS,
  /**不出4P*/
  CODE_4P_GAME_POKER_PLAY_PASS,
  /**观战*/
  CODE_GAME_WATCH,
  /**退出观战*/
  CODE_GAME_WATCH_EXIT,
  /**显示托管*/
  CODE_4P_CHANGE_TRUSTEE,
  /**显示托管状态*/
  CODE_GAME_CHANGE_TRUSTEE,
  /**自动托管状态*/
  CODE_GAME_POKER_AUTO_PLAY,
  /**加倍*/
  CODE_GAME_POKER_CHOOSE_DOUBLE,
  /**退出房间 */
  CODE_ROOM_LEAVE,
  /**游戏结束*/
  CODE_GAME_OVER,
  /**4人游戏结束*/
  CODE_4P_GAME_OVER,
}

export enum Poker__ {
  /**扑克牌3 */
  LEVEL_3 = 3,
  /**扑克牌4 */
  LEVEL_4,
  /**扑克牌5 */
  LEVEL_5,
  /**扑克牌6 */
  LEVEL_6,
  /**扑克牌7 */
  LEVEL_7,
  /**扑克牌8 */
  LEVEL_8,
  /**扑克牌9 */
  LEVEL_9,
  /**扑克牌10 */
  LEVEL_10,
  /**扑克牌J */
  LEVEL_J,
  /**扑克牌Q */
  LEVEL_Q,
  /**扑克牌K */
  LEVEL_K,
  /**扑克牌A */
  LEVEL_A,
  /**扑克牌2 */
  LEVEL_2,
  /**扑克牌 小王 */
  LEVEL_SMALL_KING,
  /**扑克牌 大王 */
  LEVEL_BIG_KING,
}

/**玩家身份 */
export enum ClientType {
  /**地主 */
  LANDLORD,
  /**农民 */
  PEASANT,
}
/**牌的类型*/
export enum PokerType {
  /**无效*/
  BLANK,
  /**方块*/
  DIAMOND,
  /**梅花*/
  CLUB,
  /**黑桃*/
  SPADE,
  /**红桃*/
  HEART,
}
//服务端返回的游戏数据结构

/**玩家加入 */
export interface JOIN_SUCCESS {
  roomType: number;
  clientId: number;
  preId: number;
  clientNickname: string;
  avatar: string;
  sex: number;
  pokers: any[];
  roomId: number;
  roomOwner: string;
  roomClientCount: number;
}

/**
 * 开始出牌
 */
export interface PLAY_START {
  currentId: number
  timeout: number
}

/**
 * 谁加的倍
 */
export interface GAME_READY {
  id: number
  iFan: number
  clientNickName: string
  status: number
  fan: number
}

/**
 * 抢地主
 */
export interface LANDLORD_ELECT {
  iFan: number
  timeout: number
  currentId: number
  preId: number
  operation: number
  fan: number
  trusted: boolean
  nextClientNickname: string
}

/**过|要不起 */
export interface POKER_PLAY_PASS {
  timeout: number
  clientId: number
  preId: number
  clientNickname: string
  lastShellId: number
  nextClientId: number
  nextClientNickname: string
  trusted: boolean
}
/**谁抢地主 */
export interface LANDLORD_ELECT {
  timeout: number
  currentId: number
  preId: number //上一个抢地主
  operation: number //0|1|2  没有操作|抢|不抢
  fan: number //倍数
  nextClientNickname: string
}

/**地主牌 */
export interface LANDLORD_CONFIRM {
  timeout: number
  roomId: number
  roomOwner: string
  roomClientCount: number
  landlordNickname: string
  landlordId: number
  additionalPokers: Poker[]
  players: Players_
}
interface Players_ {
  [key: string]: UserType_
}
interface UserType_ {
  type: number
  status: number
}
/**轮到谁出牌 */
export interface POKER_PLAY_REDIRECT {
  timeout: number
  pokers: Poker[]
  lastSellPokers: Poker[]
  lastSellClientId: number
  clientInfos: ClientInfo[]
  sellClientId: number
  sellClientNickname: string
  lastPokers: string
  trusted: boolean
}
interface ClientInfo {
  clientId: number
  clientNickname: string
  type: number
  surplus: number
  position: string
}

/**游戏开始和过程中的数据 */
export interface GAME_DATA {
  clientNickname: string
  currentId: number
  nextClientNickname: string
  timeout: number
  nextId: number
  preId: number
  players: Players
  pokerSell: Poker_1
  room: Room
  shellType: number
  cardRecords: number[]
}
interface scoreInfoType {
  finalCardRate: number;
  bombsRate: number;
  springRate: number;
  scores: any[];
  landlordRate: number;
  callRate: number;
  baseScore: number;
  maxScore: number;
  totalRate: number;
  baseRate: number;
  commonRate: number;
  onCardRate: number;
  peasantRate: number;
}
interface Room {
  scoreInfo: scoreInfoType
  playerCount: number
  nai: Poker
  id: number
  landlordId: number
  landlordPokers: Poker[]
  ownerId: string
  type: number
}
export interface Players {
  [user: string]: Player
}
interface Player {
  next: string
  pre: string
  trusted: boolean
  lost: any[]
  pokers: Poker[]
  id: number
  type: number
  status: number
  sex: number
  avatar: string
  nickname: string
}
export interface Poker_1 {
  coreLevel: number;
  score: number;
  positions: number[];//提示选牌的索引
  sellPokers: Poker[];
  sellType: number;
  straightCount: number;
}

//托管状态数据
export interface Trusted {
  clientId: number;
  nickname: string;
  trusted: boolean;
}
/**游戏结束数据 */
export interface GameOverType {
  winnerId: number;
  winnerNickname: string;
  winnerType: number;
  player: Player[];
  scores: Score[];
}

interface Score {
  fan: number;
  fromId: number;
  pokers: any[];
  score: number;
  type: number;
}

interface Player {
  id: number;
  type: number;
  nickName: string;
  fan: number;
  score: number;
  scoreInc: number;
  pokers: Poker[];
}


export interface Poker {
  level: number;
  type: number;
}